import { createServer, Server as HttpServer } from 'http';
import { Server } from 'socket.io';
// 扩展 NodeJS 的 Global 接口
declare global {
  var _io: Server | undefined;
  var _httpServer: HttpServer | undefined;
}

// 单例模式保证socket的初始化只在服务器启动的时候运行
const initializeSocketIO = (httpServer: HttpServer) => {
  console.log("Initializing new Socket.IO server...");
  
  const io = new Server(httpServer, {
    cors: {
      origin: 'http://localhost:3000', // 在生产环境中应配置为具体的域名
      methods: ['GET', 'POST'],
      credentials: true
    },
  });

  const onlineUsers = new Map<string, string>(); // Map<userId, socketId>
  
  io.use((socket, next) => {
    const cookie = socket.handshake.headers.cookie;
    if (!cookie) {
      return next(new Error('Authentication error: No cookie provided'));
    }
    const userId = cookie.split(';').find(c => c.trim().startsWith('userId='))?.split('=')[1];
    if (!userId) {
      return next(new Error('Authentication error: userId not found in cookie'));
    }
    (socket as any).userId = userId;
    next();
  });

  io.on('connection', (socket) => {
    const userId = (socket as any).userId;
    console.log(`[Socket.IO] New connection: ${socket.id}, UserID: ${userId}`);

    if (userId) {
      console.log(`[Socket.IO] User ${userId} connected with socket ${socket.id}`);
      socket.join(userId); // 用户加入以自己id命名的房间
      onlineUsers.set(userId, socket.id);
      socket.broadcast.emit('userOnline', userId);
    } else {
      console.log(`[Socket.IO] a user connected with socket ${socket.id}, but no userId provided.`);
    }

    socket.on('joinGroup', (groupId: string) => {
      if (!groupId) return;
      console.log(`[Socket.IO] Socket ${socket.id} joined group ${groupId}`);
      socket.join(groupId);
    });

    socket.on('disconnect', () => {
      console.log(`[Socket.IO] Connection disconnected: ${socket.id}`);
      for (const [key, value] of onlineUsers.entries()) {
        if (value === socket.id) {
          onlineUsers.delete(key);
          io.sockets.emit('userOffline', key);
          console.log(`[Socket.IO] User ${key} disconnected.`);
          break;
        }
      }
    });
  });

  return io;
};

let io: Server;

if (process.env.NODE_ENV === 'development') {
  if (!global._httpServer) {
    console.log('--- Creating new HTTP server for Socket.IO (development) ---');
    global._httpServer = createServer();
  }
  if (!global._io) {
    global._io = initializeSocketIO(global._httpServer);

    const PORT = parseInt(process.env.SOCKET_PORT || '8888', 10);
    // @ts-ignore
    if (!global._httpServer.listening) {
        global._httpServer.listen(PORT, () => {
        console.log(`Socket.IO server is running on port ${PORT}`);
      });
    }
  }
  io = global._io;
} else {
    console.log('--- Creating new HTTP server for Socket.IO (production) ---');
    const httpServer = createServer();
    io = initializeSocketIO(httpServer);
    const PORT = parseInt(process.env.SOCKET_PORT || '8888', 10);
    httpServer.listen(PORT, () => {
        console.log(`Socket.IO server is running on port ${PORT}`);
    });
}


export { io }; 